package VWorldGameStudio;

import FCRendering.FCRMaster;
import lombok.Getter;
import lombok.Setter;

import java.awt.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 地图属性类
 */
public class FCMap extends Sprite {
    // 地图名
    @Setter
    private String name;
    // 地图信息
    private String info;
    // 地图尺寸
    private int width;
    private int height;
    // 大背景材质
    private String backgroundUrl;
    // 背景图片
    private Image backgroundImage;
    // 地图地面数据，存放方块名称（草地，地板等）
    private String[][] lowerPlace;
    // 地图地面数据，存放放置方块名称（草地上的树，地板上的桌子等）
    private String[][] upperPlace;
    // 地图的实体碰撞数据记录，0为人物、坦克可通过，1为人物可通过，2为不可通过。lowerPlace
    private int[][] collisionLevelLowerPlace;
    // 地图的实体碰撞数据记录，0为无实体，1为人物、坦克可通过，2为人物可通过。upperPlace
    private int[][] collisionLevelUpperPlace;
    // 地图上时间触发点极其触发事件名称,包括宝物
    private String[][] eventName;

    // 地图上的坐标和npcid
    private HashMap<String, String> mapNpc;
    // 地图上的坐标和tankid
    private HashMap<String, String> mapTank;

    // 地图上的坐标和地图动画id
    @Getter
    private HashMap<String, String> mapAnimation;

    @Getter//动态添加的动画id集合
    private ConcurrentHashMap<String, String> dynamicMapAnimation = new ConcurrentHashMap<>();

    @Getter
    private ArrayList<FCMapAndMsEntity> mapAndMsEntities = new ArrayList<>();

    /**
     * 新建地图
     *
     * @param name
     * @param width
     * @param height
     * @param info
     * @param url
     */
    public void createMap(String name, int width, int height, String info, String url) {
        this.name = name;
        this.width = width;
        this.height = height;
        this.info = info;
        this.backgroundUrl = url;
        this.backgroundImage = Toolkit.getDefaultToolkit().getImage(url);
        lowerPlace = new String[width][height];
        upperPlace = new String[width][height];
        eventName = new String[width][height];
        collisionLevelLowerPlace = new int[width][height];
        collisionLevelUpperPlace = new int[width][height];

        for (int i = 0; i < width; i++) {
            for (int j = 0; j < height; j++) {
                lowerPlace[i][j] = "v";
                upperPlace[i][j] = "v";
                eventName[i][j] = "v";
                collisionLevelLowerPlace[i][j] = 0;
                collisionLevelUpperPlace[i][j] = 0;

            }
        }
        mapNpc = new HashMap<>();
        mapTank = new HashMap<>();
        mapAnimation = new HashMap<>();
    }

    /**
     * 注册地图
     *
     * @param name
     * @param info
     * @param width
     * @param height
     * @param lowerPlace
     * @param upperPlace
     * @param collisionLevelLowerPlace
     * @param collisionLevelUpperPlace
     * @param eventName
     * @param url
     * @param npc
     * @param monsterID
     * @param tank
     */
    public void registerMap(String name, String info, int width, int height, String[][] lowerPlace, String[][] upperPlace,
                            int[][] collisionLevelLowerPlace, int[][] collisionLevelUpperPlace, String[][] eventName, String url, HashMap<String, String> npc,
                            String[][] monsterID, HashMap<String, String> tank, HashMap<String, String> mapAni, ArrayList<FCMapAndMsEntity> msList) {
        this.name = name;
        this.info = info;
        this.width = width;
        this.height = height;
        this.lowerPlace = lowerPlace;
        this.upperPlace = upperPlace;
        this.eventName = eventName;
        this.collisionLevelLowerPlace = collisionLevelLowerPlace;
        this.collisionLevelUpperPlace = collisionLevelUpperPlace;
        this.backgroundUrl = url;
        this.backgroundImage = Toolkit.getDefaultToolkit().getImage(url);
        this.mapNpc = npc;
        this.mapTank = tank;
        this.mapAnimation = mapAni;
        mapAndMsEntities = msList;
    }

    public int getMapWidth() {
        return width;
    }

    public int getMapHeight() {
        return height;
    }

    public String getName() {
        return name;
    }

    public String getInfo() {
        return info;
    }

    public String[][] getLowerPlace() {
        return lowerPlace;
    }

    public String[][] getUpperPlace() {
        return upperPlace;
    }

    public int[][] getCollisionLevelLowerPlace() {
        return collisionLevelLowerPlace;
    }

    public int[][] getCollisionLevelUpperPlace() {
        return collisionLevelUpperPlace;
    }

    public String[][] getEventName() {
        return eventName;
    }

    public String getBackgroundURL() {
        return this.backgroundUrl;
    }

    public Image getBackgroundImage() {
        return this.backgroundImage;
    }

    /**
     * 根据coor获取monsterID
     *
     * @param x
     * @param y
     * @return
     */
    public String getMapMonsterIDOfCoor(int x, int y) {
        FCMapAndMsEntity findArea = null;
        for (FCMapAndMsEntity msA : mapAndMsEntities) {
            if (msA.startXY[0] <= x && msA.startXY[1] <= y && msA.endXY[0] >= x && msA.endXY[1] >= y) {
                findArea = msA;
                break;
            }
        }

        if (findArea != null) {
            StringBuilder sb = new StringBuilder();
            for (FCMapAndMsEntity.MS ms : findArea.getMonsterIds()) {
                //只拿取未打的悬赏boss
                if (sb.toString().length() > 0) {
                    sb.append(",");
                }
                sb.append(ms.id);
            }
            return sb.toString();
        } else {
            return "";
        }
    }

    //获取触发率
    public ArrayList<Integer> getTriggerRate(int x, int y) {
        FCMapAndMsEntity findArea = null;
        for (FCMapAndMsEntity msA : mapAndMsEntities) {
            if (msA.startXY[0] <= x && msA.startXY[1] <= y && msA.endXY[0] >= x && msA.endXY[1] >= y) {
                findArea = msA;
                break;
            }
        }

        if (findArea != null) {
            ArrayList<Integer> ret = new ArrayList<>(0);
            for (FCMapAndMsEntity.MS ms : findArea.getMonsterIds()) {
                ret.add(ms.triggerLvel);
            }
            return ret;
        } else {
            return null;
        }
    }

    /**
     * 根据coor获取npcId，key不存在时返回null
     *
     * @param coor
     * @return
     */
    public String getMapNpcNameOfCoor(String coor) {
        return mapNpc.containsKey(coor) ? mapNpc.get(coor) : "null";
    }

    /**
     * 设置npc所在位置
     *
     * @param name
     * @param coor
     * @return
     */
    public FCMap setMapNpcOfCoor(String name, String coor) {
        this.mapNpc.put(coor, name);
        return this;
    }

    /**
     * 删除npc
     *
     * @param coor
     * @return
     */
    public FCMap deleteMapNpcOfCoor(String coor) {
        this.mapNpc.remove(coor);
        return this;
    }

    /**
     * 根据coor获取tankId
     *
     * @param coor
     * @return
     */
    public String getMapTankNameOfCoor(String coor) {
        if (mapTank.size() > 0 && mapTank.containsKey(coor)) {
            return mapTank.get(coor);
        }
        return "null";
    }

    /**
     * 设置tank所在位置
     *
     * @param name
     * @param coor
     * @return
     */
    public FCMap setMapTankOfCoor(String name, String coor) {
        this.mapTank.put(coor, name);
        return this;
    }

    /**
     * 删除tank
     *
     * @param coor
     * @return
     */
    public FCMap deleteMapTankOfCoor(String coor) {
        mapTank.remove(coor);
        return this;
    }

    /**
     * 获取npc列表
     *
     * @return
     */
    public HashMap<String, String> getMapNpcHashMap() {
        return mapNpc;
    }

    /**
     * 获取tank列表
     *
     * @return
     */
    public HashMap<String, String> getMapTankHashMap() {
        return mapTank;
    }

    /**
     * 根据坐标获取该坐标点的black名称
     *
     * @param x
     * @param y
     * @return
     */
    public String getUnplaceNameOfCoor(int x, int y) {
        return lowerPlace[x][y];
    }

    /**
     * 根据坐标获取该点的place名称
     *
     * @param x
     * @param y
     * @return
     */
    public String getPlaceNameOfCoor(int x, int y) {
        return (x > -1 && x < upperPlace.length && y > -1 && y < upperPlace[0].length) ? upperPlace[x][y] : "null";
    }

    /**
     * 根据坐标点设置该点的block
     *
     * @param x
     * @param y
     * @param bl
     * @return
     */
    public FCMap setMapBlockOfCoor(int x, int y, FCBlock bl) {
        boolean isnew = lowerPlace[x][y].equals(bl.getBlockID()) || upperPlace[x][y].equals(bl.getBlockID());
        boolean qwee = bl.getBlockType().equals("unplace");
        if (qwee)
            lowerPlace[x][y] = (!isnew) ? bl.getBlockID() : "v";
        else
            upperPlace[x][y] = (!isnew) ? bl.getBlockID() : "v";
        int[][] qwe = bl.getBlockCoor();
        for (int i = 0; i < qwe.length; i++) {
            for (int j = 0; j < qwe[qwe.length - 1 - i].length; j++) {
                if (qwee) {
                    collisionLevelLowerPlace[x - i][y + j] = (!isnew) ? qwe[qwe.length - 1 - i][j] : 0;
                } else {
                    collisionLevelUpperPlace[x - i][y + j] = (!isnew) ? qwe[qwe.length - 1 - i][j] : 0;
                }
            }
        }
        return this;
    }

    /**
     * 根据坐标点设置该点的事件
     *
     * @param x
     * @param y
     * @param eventname
     * @return
     */
    public FCMap setMapEventOfCoor(int x, int y, String eventname) {
        eventName[x][y] = eventname;
        return this;
    }

    // 初始化地图实体碰撞数据
    public FCMap newMapEntity() {
        for (int i = 0; i < collisionLevelLowerPlace.length; i++)
            for (int j = 0; j < collisionLevelLowerPlace[i].length; j++) {
                collisionLevelLowerPlace[i][j] = 0;
                collisionLevelUpperPlace[i][j] = 0;
            }
        return this;
    }

    /**
     * 根据坐标点设置该点的entity
     *
     * @param x
     * @param y
     * @param bl
     * @return
     */
    public FCMap setMapEntityOfCoor(int x, int y, FCBlock bl) {
        boolean qwee = bl.getBlockType().equals("unplace");
        int[][] qwe = bl.getBlockCoor();
        for (int i = 0; i < qwe.length; i++)
            for (int j = 0; j < qwe[qwe.length - 1 - i].length; j++)
                if (qwee)
                    collisionLevelLowerPlace[x - i][y + j] = qwe[qwe.length - 1 - i][j];
                else
                    collisionLevelUpperPlace[x - i][y + j] = qwe[qwe.length - 1 - i][j];
        return this;
    }

    /**
     * 获取该点的最高实体权限
     *
     * @param x
     * @param y
     * @return
     */
    public int getMapEntityOfCoor(int x, int y) {
        if (x >= 0 && x < width && y >= 0 && y < height) {
            return (collisionLevelUpperPlace[x][y] > collisionLevelLowerPlace[x][y]) ? collisionLevelUpperPlace[x][y] : collisionLevelLowerPlace[x][y];
        } else {
            return 4;
        }
    }

    /**
     * 根据坐标获取事件名
     *
     * @param x
     * @param y
     * @return
     */
    public String getEventNameOfCoor(int x, int y) {
        return (x >= 0 && x < eventName.length && y >= 0 && y < eventName[0].length) ? eventName[x][y] : "null";
    }

    /**
     * 获取地图尺寸
     *
     * @return
     */
    public int[] getMapSize() {
        return new int[]{width, height};
    }

    //coor x+"*"+y
    public FCMap setMapAnimationOfCoor(String name, String coor) {
        this.mapAnimation.put(coor, name);
        return this;
    }

    public String getMapAnimationOfCoor(String coor) {
        String ret = mapAnimation.get(coor);
        return ret == null ? "null" : ret;
    }

    /**
     * @param coor
     * @return
     */
    public FCMap deleteMapAnimationOfCoor(String coor) {
        this.mapAnimation.remove(coor);
        return this;
    }

    public void dynamicAddMapAnimation(String aniName, String coor) {
        dynamicMapAnimation.put(aniName, coor);
    }

    public void dynamicRemoveMapAnimation(String aniName) {
        if (dynamicMapAnimation.containsKey(aniName)) {
            dynamicMapAnimation.remove(aniName);
        }
    }

    public void removeAlldynamicMapAnimation() {
        dynamicMapAnimation.clear();
    }

    public void addMapAndMsEntities(FCMapAndMsEntity entity) {
        if (!mapAndMsEntities.contains(entity)) {
            mapAndMsEntities.add(entity);
            //TODO 排序，按等级大的排到小的
            Comparator com2 = new Comparator<FCMapAndMsEntity>() {
                @Override
                public int compare(FCMapAndMsEntity o1, FCMapAndMsEntity o2) {
                    return o2.getLevel() - o1.getLevel();
                }
            };
            Collections.sort(mapAndMsEntities, com2);
        }
    }
}
